package com.zhiche.lisa.integration.inteface.erp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.google.common.collect.Lists;
import com.qiniu.storage.model.DefaultPutRet;
import com.zhiche.lisa.core.enums.IntegrationURIEnum;
import com.zhiche.lisa.core.enums.SystemEnum;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.supports.RestfulResponse;
import com.zhiche.lisa.core.utils.HttpClientUtil;
import com.zhiche.lisa.core.utils.qiniu.util.QiniuUtils;
import com.zhiche.lisa.core.utils.redislog.RedisLogUtil;
import com.zhiche.lisa.integration.anno.AnnoUtil;
import com.zhiche.lisa.integration.dao.model.ImportLogHistory;
import com.zhiche.lisa.integration.dao.model.PushSubSystem;
import com.zhiche.lisa.integration.dto.carrier.CarrierErpDto;
import com.zhiche.lisa.integration.dto.carrier.DriverErpDto;
import com.zhiche.lisa.integration.dto.carrier.SupplierErpDto;
import com.zhiche.lisa.integration.dto.carrier.TrailerErpDto;
import com.zhiche.lisa.integration.dto.order.ErpShipLine;
import com.zhiche.lisa.integration.dto.order.ErpShipping;
import com.zhiche.lisa.integration.dto.order.ShipTaskDTO;
import com.zhiche.lisa.integration.dto.order.ShipmentDTO;
import com.zhiche.lisa.integration.service.IImportLogService;
import com.zhiche.lisa.integration.service.IPushSubSystemService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Created by zhaoguixin on 2018/7/21.
 */
@Service
public class ErpShippingService {

    public Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Value("${erp.url}")
    private String erpUrl;

    //连接超时时间
    @Value("${erp.socketTimeout}")
    private int socketTimeout;


    @Value("${logRedis.isTest}")
    private boolean isTest;

    @Autowired
    private IImportLogService importLogService;
    @Autowired
    private IPushSubSystemService pushSubSystemService;
    @Autowired
    private IImportLogService iImportLogService;

    private static final String NEWSET_SHIP_URI = "/ship/getNewestShipByLicense";

    /**
     * 通过车牌号抓取EPR调度指令
     *
     * @param plate
     * @return
     */
    public ShipmentDTO grabErpShipment(String plate) throws Exception {
        Date startDate = new Date();
        Date endDate;
        ErpShipping erpShipping = null;
        String qiniuKey;

        String restfulResponse = grabNewestShipByPlate(plate);
        if (!StringUtils.isEmpty(restfulResponse)) {
            erpShipping = getNewestShip(restfulResponse);
            if (Objects.isNull(erpShipping)) return null;
        }
        DefaultPutRet putRet = QiniuUtils.uploadString(restfulResponse);
        qiniuKey = putRet.key;

        ShipmentDTO shipmentDTO = new ShipmentDTO();
        AnnoUtil.copyPropertiesByAnno(erpShipping, shipmentDTO);
        for (ErpShipLine erpShipLine : erpShipping.getShipLineList()) {
            ShipTaskDTO shipTaskDTO = new ShipTaskDTO();
            AnnoUtil.copyPropertiesByAnno(erpShipLine, shipTaskDTO);
            shipmentDTO.addShipTaskDTO(shipTaskDTO);
        }
        endDate = new Date();
        ImportLogHistory importLogHistory = new ImportLogHistory();
        importLogHistory.setSourceSys("erp");
        importLogHistory.setSourceKey(shipmentDTO.getShipmentId());
        importLogHistory.setType("10");
        importLogHistory.setDataStorageKey(qiniuKey);
        importLogHistory.setImportStartTime(startDate);
        importLogHistory.setImportEndTime(endDate);
        importLogService.saveImportLog(importLogHistory);
        return shipmentDTO;
    }

    /**
     * 根据车牌号获取最新调度指令
     *
     * @param strResult
     * @return
     */
    private ErpShipping getNewestShip(String strResult) {
        ErpShipping erpShipping = null;
        if (!StringUtils.isEmpty(strResult)) {
            RestfulResponse<ErpShipping> result = JSON.parseObject(strResult, new
                    TypeReference<RestfulResponse<ErpShipping>>() {
                    });
            erpShipping = result.getData();
        }
        return erpShipping;
    }

    private String grabNewestShipByPlate(String license) {
        List<NameValuePair> params = Lists.newArrayList();
        params.add(new BasicNameValuePair("vclicense", license));
        String result = HttpClientUtil.get(erpUrl + NEWSET_SHIP_URI, null, params, socketTimeout);
        return result;
    }

    /**
     * ERP自有车队--牵引车(运力平台推送OTM时,自有车队推送ERP)
     */
    public void carrierPushErp(CarrierErpDto carrierErpDto) {
        String paramJson = JSONObject.toJSONString(carrierErpDto);
        LOGGER.info("integration 推送牵引车参数:{}", paramJson);
        //导入日志
        ImportLogHistory importLogHistory = new ImportLogHistory();
        importLogHistory.setSourceSys("lpsm");
        importLogHistory.setSourceKey(carrierErpDto.getId());
        importLogHistory.setType(IntegrationURIEnum.ERP_CARRIER.getCode());
        importLogHistory.setImportStartTime(new Date());
        importLogHistory.setImportEndTime(new Date());
        new Thread(() -> {
            LOGGER.info("开始保存导入日志---------------");
            try {
                iImportLogService.saveImportLogToQiniu(importLogHistory, paramJson);
            } catch (Exception e) {
                LOGGER.error("日志保存失败---------------");
            }
            LOGGER.info("完成日志保存---------------");
        }).start();

        Wrapper<PushSubSystem> ew = new EntityWrapper<>();
        ew.eq("type", IntegrationURIEnum.ERP_CARRIER.getCode());
        List<PushSubSystem> pushSubSystems = pushSubSystemService.selectList(ew);
        if (CollectionUtils.isNotEmpty(pushSubSystems)) {
            for (PushSubSystem subSystem : pushSubSystems) {
                String url = subSystem.getUrl();
                Integer socketTimeOut = subSystem.getSocketTimeOut();
                String result = null;
                try {
                    LOGGER.info("ErpShippingService.carrierPushErp url:{},PARAM:{} result:{}", url, paramJson);
                    result = HttpClientUtil.postJson(url, null, paramJson, socketTimeOut);
                    LOGGER.info("ErpShippingService.carrierPushErp url:{}, result:{}", url, result);
                    if (StringUtils.isBlank(result)) {
                        throw new BaseException("erp接口返回为空");
                    }
                    JSONObject jsonObject = JSON.parseObject(result);
                    boolean success = jsonObject.getBoolean("success");
                    int isSuc=0;
                    if (success){
                        isSuc=1;
                    }
                    RedisLogUtil.addSysLogs(SystemEnum.LSPM.getCode(),SystemEnum.INTEGRATION.getCode(),"carrier"+carrierErpDto.getId(), JSON.toJSONString(carrierErpDto),"/erp-api/carrierPushErp",3,isSuc,jsonObject.get("message").toString(),isTest);
                } catch (Exception e) {
                    LOGGER.error("ErpShippingService.carrierPushErp url:{} 连接超时--> error:{}", url, e);
                }
            }
        }
    }

    /**
     * ERP自有车队--挂车(运力平台推送OTM时,自有车队推送ERP)
     */
    public void trailerPushErp(TrailerErpDto trailerErpDto) {
        String paramJson = JSONObject.toJSONString(trailerErpDto);
        LOGGER.info("integration 推送挂车参数:{}", paramJson);
        //导入日志
        ImportLogHistory importLogHistory = new ImportLogHistory();
        importLogHistory.setSourceSys("lpsm");
        importLogHistory.setSourceKey(trailerErpDto.getId().toString());
        importLogHistory.setType(IntegrationURIEnum.ERP_TRAILER.getCode());
        importLogHistory.setImportStartTime(new Date());
        importLogHistory.setImportEndTime(new Date());
        new Thread(() -> {
            LOGGER.info("开始保存导入日志---------------");
            try {
                iImportLogService.saveImportLogToQiniu(importLogHistory, paramJson);
            } catch (Exception e) {
                LOGGER.error("日志保存失败---------------");
            }
            LOGGER.info("完成日志保存---------------");
        }).start();

        Wrapper<PushSubSystem> ew = new EntityWrapper<>();
        ew.eq("type", IntegrationURIEnum.ERP_TRAILER.getCode());
        List<PushSubSystem> pushSubSystems = pushSubSystemService.selectList(ew);
        if (CollectionUtils.isNotEmpty(pushSubSystems)) {
            for (PushSubSystem subSys : pushSubSystems) {
                String url = subSys.getUrl();
                Integer socketTimeOut = subSys.getSocketTimeOut();
                String result = null;
                try {
                    LOGGER.info("ErpShippingService.trailerPushErp url:{},param:{}", url, paramJson);
                    result = HttpClientUtil.postJson(url, null, paramJson, socketTimeOut);
                    LOGGER.info("ErpShippingService.trailerPushErp url:{} result:{}", url, result);

                    if (StringUtils.isBlank(result)) {
                        throw new BaseException("erp接口返回为空");
                    }
                    JSONObject jsonObject = JSON.parseObject(result);
                    boolean success = jsonObject.getBoolean("success");
                    int isSuc=0;
                    if (success){
                        isSuc=1;
                    }
                    RedisLogUtil.addSysLogs(SystemEnum.LSPM.getCode(),SystemEnum.INTEGRATION.getCode(),"trailer"+trailerErpDto.getId(), JSON.toJSONString(trailerErpDto),"/erp-api/trailerPushErp",3,isSuc,jsonObject.get("message").toString(),isTest);
                } catch (Exception e) {
                    LOGGER.error("ErpShippingService.trailerPushErp url:{} 连接超时--> error:{}", url, e);
                }
            }
        }

    }

    /**
     * ERP自有车队--司机(运力平台推送OTM时,自有车队推送ERP)
     */
    public void driverPushErp(DriverErpDto driverErpDto) {
        //导入日志
        driverErpDto.setIdNo(driverErpDto.getLicenseId());
        String paramJson = JSONObject.toJSONString(driverErpDto);
        LOGGER.info("integration 推送司机参数:{}", paramJson);
        ImportLogHistory importLogHistory = new ImportLogHistory();
        importLogHistory.setSourceSys("lpsm");
        importLogHistory.setSourceKey(driverErpDto.getId().toString());
        importLogHistory.setType(IntegrationURIEnum.ERP_DRIVER.getCode());
        importLogHistory.setImportStartTime(new Date());
        importLogHistory.setImportEndTime(new Date());
        new Thread(() -> {
            LOGGER.info("开始保存导入日志---------------");
            try {
                iImportLogService.saveImportLogToQiniu(importLogHistory, paramJson);
            } catch (Exception e) {
                LOGGER.error("日志保存失败---------------");
            }
            LOGGER.info("完成日志保存---------------");
        }).start();

        Wrapper<PushSubSystem> ew = new EntityWrapper<>();
        ew.eq("type", IntegrationURIEnum.ERP_DRIVER.getCode());
        List<PushSubSystem> pushSubSystems = pushSubSystemService.selectList(ew);
        if (CollectionUtils.isNotEmpty(pushSubSystems)) {
            for (PushSubSystem subSys : pushSubSystems) {
                String url = subSys.getUrl();
                Integer socketTimeOut = subSys.getSocketTimeOut();
                String result = null;
                try {
                    LOGGER.info("ErpShippingService.driverPushErp url:{}, param{}", url, paramJson);
                    result = HttpClientUtil.postJson(url, null, paramJson, socketTimeOut);
                    LOGGER.info("ErpShippingService.driverPushErp url:{} result:{}", url, result);

                    if (StringUtils.isBlank(result)) {
                        throw new BaseException("erp接口返回为空");
                    }
                    JSONObject jsonObject = JSON.parseObject(result);
                    boolean success = jsonObject.getBoolean("success");
                    int isSuc=0;
                    if (success){
                        isSuc=1;
                    }
                    RedisLogUtil.addSysLogs(SystemEnum.LSPM.getCode(),SystemEnum.INTEGRATION.getCode(),"driver"+driverErpDto.getId(), JSON.toJSONString(driverErpDto),"/erp-api/driverPushErp",3,isSuc,jsonObject.get("message").toString(),isTest);

                } catch (Exception e) {
                    LOGGER.error("ErpShippingService.driverPushErp url:{} 连接超时--> error:{}", url, e);
                }
            }
        }

    }

    /**
     * ERP自有车队--供方（车队）(运力平台推送OTM时,自有车队推送ERP)
     */
    public void supplierPushErp(SupplierErpDto supplierErpDto) {
        String paramJson = JSONObject.toJSONString(supplierErpDto);
        LOGGER.info("integration 推送供方(车队)参数:{}", paramJson);
        //导入日志
        ImportLogHistory importLogHistory = new ImportLogHistory();
        importLogHistory.setSourceSys("lpsm");
        importLogHistory.setSourceKey(supplierErpDto.getId().toString());
        importLogHistory.setType(IntegrationURIEnum.ERP_SUPPLIER.getCode());
        importLogHistory.setImportStartTime(new Date());
        importLogHistory.setImportEndTime(new Date());
        new Thread(() -> {
            LOGGER.info("开始保存导入日志---------------");
            try {
                iImportLogService.saveImportLogToQiniu(importLogHistory, supplierErpDto.toString());
            } catch (Exception e) {
                LOGGER.error("日志保存失败---------------");
            }
            LOGGER.info("完成日志保存---------------");
        }).start();

        Wrapper<PushSubSystem> ew = new EntityWrapper<>();
        ew.eq("type", IntegrationURIEnum.ERP_SUPPLIER.getCode());
        List<PushSubSystem> pushSubSystems = pushSubSystemService.selectList(ew);
        if (CollectionUtils.isEmpty(pushSubSystems) || pushSubSystems.size() <= 0) {
            throw new BaseException("为查询到对应url");
        }
        if (CollectionUtils.isNotEmpty(pushSubSystems)) {
            for (PushSubSystem subSys : pushSubSystems) {
                String url = subSys.getUrl();
                Integer socketTimeOut = subSys.getSocketTimeOut();
                LOGGER.info("ErpShippingService.supplierPushErp url:{},param:{}", url, paramJson);
                String result = HttpClientUtil.postJson(url, null, paramJson, socketTimeOut);
                LOGGER.info("ErpShippingService.supplierPushErp result:" + result);
                if (StringUtils.isBlank(result)) {
                    throw new BaseException("erp接口返回为空");
                }
                JSONObject jsonObject = JSON.parseObject(result);
                boolean success = jsonObject.getBoolean("success");
                int isSuc=0;
                if (success){
                    isSuc=1;
                }
                RedisLogUtil.addSysLogs(SystemEnum.LSPM.getCode(),SystemEnum.INTEGRATION.getCode(),"fleet"+supplierErpDto.getId(), JSON.toJSONString(supplierErpDto),"/erp-api/supplierPushErp",3,isSuc,jsonObject.get("message").toString(),isTest);
                if (!success) {
                    throw new BaseException(jsonObject.getString("message"));
                }
            }
        }

    }

}
